package org.tgcloud.group.service.task;

import cn.hutool.core.map.MapUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.IOUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;
import org.apache.poi.ss.usermodel.PictureData;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import org.tgcloud.group.core.*;
import org.tgcloud.group.core.ExportUtils.ExcelUtils;
import org.tgcloud.group.core.fileUtils.waterMarkFileUtils.ImgCompress;
import org.tgcloud.group.repository.MjGoodSkuMapper;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.InetAddress;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static org.aspectj.weaver.tools.cache.SimpleCacheFactory.path;
import static org.tgcloud.group.core.ExportUtils.PictureUtil.getPictureFromExcel;

/**
 * @author: zhy
 * @create: 2023-10-30 14:52
 * @description: 文档上传图片任务
 */
@Slf4j
@Component
public class ExcelPicTask {


    private static final String XLSX = ".xlsx";
    private static final String XLS = ".xls";
    private static final String key = "del_image_list";
    private static final String fileKey = "need_del_app_show_list";
    private static final String delAddFileKey = "del_file_name_list:";

    @Autowired
    private MjGoodSkuMapper skuMapper;

    // 删除缓存中后台上传的表单信息中的图片文件
    @Scheduled(cron = "0 45 23 * * ?")
    public void doDelPicByManagerAddRedisFileList() throws Exception{
        InetAddress inetAddress = InetAddress.getLocalHost();
        String ipAddress = inetAddress.getHostAddress();
        System.out.println("doDelPicByManagerAddRedisFileList服务器IP地址是: " + ipAddress);
        if (StringUtil.isNotBlank(ipAddress) && ipAddress.equals("172.31.192.16")){
            return;
        }
        String key = "del_file_name_list:" + DateUtil.getyyyyMMddToRedis(new Date()) + ":*";
        String picDirectoryPath = ExcelUtils.doViewFilePath(GlobalStatic.downloadPic);
        Set<String> cacheSet = RedisUtil.keys(key);
        if (cacheSet != null && cacheSet.size() > 0){
            for (String s : cacheSet){
                String[] split = s.split(":");
                String downloadPath = split[split.length - 1];
                String directoryPath = picDirectoryPath; // 替换为你的目录路径
                String[] split1 = downloadPath.split(".x");
                String pattern = split1[0]; // 替换为你想匹配的文件模式
                File directory = new File(directoryPath);
                // 使用匿名内部类实现FilenameFilter接口
                File[] matchingFiles = directory.listFiles(new FilenameFilter() {
                    public boolean accept(File dir, String name) {
                        return name.contains(pattern);
                    }
                });
                for (File file : matchingFiles){
                    if (file.exists()){
                        file.delete();
                    }
                }
            }
        }
    }

    // 删除缓存中后台上传的表单信息
    @Scheduled(cron = "0 55 23 * * ?")
    public void doDelManagerAddRedisFileList() throws Exception{
        InetAddress inetAddress = InetAddress.getLocalHost();
        String ipAddress = inetAddress.getHostAddress();
        System.out.println("doDelManagerAddRedisFileList服务器IP地址是: " + ipAddress);
        if (StringUtil.isNotBlank(ipAddress) && ipAddress.equals("172.31.192.16")){
            return;
        }
        String key = "del_file_name_list:" + DateUtil.getyyyyMMddToRedis(new Date()) + ":*";
        Set<String> cacheSet = RedisUtil.keys(key);
        if (cacheSet != null && cacheSet.size() > 0){
            for (String s : cacheSet){
                String path = RedisUtil.getCacheObject(s);
                doDelFile(path);
                RedisUtil.deleteObject(s);
            }
        }
    }

    public void doDelRedisAddFile(String fileName){
        RedisUtil.deleteObject(delAddFileKey + DateUtil.getyyyyMMddToRedis(new Date()) + ":" + fileName + ".xls");
        RedisUtil.deleteObject(delAddFileKey + DateUtil.getyyyyMMddToRedis(new Date()) + ":" + fileName + ".xlsx");
    }

    @Scheduled(cron = "0 50 22 * * ?")
    public void doDelRedisFile() throws Exception{
        InetAddress inetAddress = InetAddress.getLocalHost();
        String ipAddress = inetAddress.getHostAddress();
        System.out.println("doDelRedisFile服务器IP地址是: " + ipAddress);
        if (StringUtil.isNotBlank(ipAddress) && ipAddress.equals("172.31.192.16")){
            return;
        }
        boolean b = RedisUtil.existKey(fileKey);
        if (b){
            List<String> cacheList = RedisUtil.getCacheObject(fileKey);
            if (!BeanUtil.isNullList(cacheList)){
                for (String path : cacheList){
                    doDelFile(path);
                }
                RedisUtil.deleteObject(fileKey);
            }
        }
    }

    @Async
    public void doDelFile(String filePath){
        File file = new File(filePath);
        if (!file.exists()) {
            log.info("Folder does not exist");
        }
        if (!file.isFile()) {
            log.info("Not a File");
        }
        file.delete(); // 删除文件
    }

    @Scheduled(cron = "0 50 22 * * ?")
    public void doDelSkuPic() throws Exception{
        InetAddress inetAddress = InetAddress.getLocalHost();
        String ipAddress = inetAddress.getHostAddress();
        System.out.println("doDelSkuPic服务器IP地址是: " + ipAddress);
        if (StringUtil.isNotBlank(ipAddress) && ipAddress.equals("172.31.192.16")){
            return;
        }
        boolean b = RedisUtil.existKey(key);
        if (b){
            log.info("开始清理图片1");
            List<String> cacheList = RedisUtil.getCacheList(key);
            if (!BeanUtil.isNullList(cacheList)){
                skuMapper.updatePicUrlByUrl(cacheList);
                log.info("开始清理图片2");
                RedisUtil.deleteObject(key);
                log.info("开始清理图片3");
            }
        }
    }



    @Async
    public void doAddPic(String fileName, MultipartFile multipartFile,Integer picNum){
        try {
            String path = ExcelUtils.doFolderFilePath(GlobalStatic.downloadPic);
            String originalFilename = multipartFile.getOriginalFilename();
            String prefix = originalFilename.substring(originalFilename.lastIndexOf("."));
            File file = new File(ExcelUtils.doFolderFilePath(GlobalStatic.downloadPath) + File.separator + fileName + prefix);
            MultipartFile mFile = getMultipartFile(file);
            String picName = fileName;
            Workbook book = getWorkbookOut(mFile);
            if (book == null) {
            }else {
                Sheet sheet = book.getSheetAt(0);
                // 首行下标
                int rowStart = sheet.getFirstRowNum();
                // 尾行下标
                int rowEnd = sheet.getLastRowNum();
                for (int i = rowStart + 1; i <= rowEnd; i++) {
                    Integer rowNum = i;
                    String pic = "pic_" + picName + "_" + rowNum;
                    String url = pic + ".png";
                    //获取图片数据
                    Map<String, PictureData> map = getPictureFromExcel(file, 1);
                    if (null == map || MapUtil.isEmpty(map) || picNum == null){
                        // 处理没有图片的数据
                        if (StringUtil.isNotBlank(url)){
                            String pUrl = ExcelUtils.doViewFilePath(GlobalStatic.viewPicPath) + File.separator + url;
                            List<String> urls = new ArrayList<>();
                            urls.add(pUrl);
                            RedisUtil.setCacheList(key, urls);
                        }
                    }else {
                        PictureData picData = (PictureData)map.get((rowNum)+"-"+picNum);
                        if (null != picData){
                            byte[] data = picData.getData();
                            BufferedImage read = ImageIO.read(new ByteArrayInputStream(data));
                            FileOutputStream out = new FileOutputStream(path + File.separator + url);
                            BufferedOutputStream bos = new BufferedOutputStream(out);
                            out.write(data);
                            out.close();
                            bos.close();
                            ImgCompress imgCom = new ImgCompress(path + File.separator + url);
                            imgCom.resize(read.getWidth(), read.getHeight(), path + File.separator + url);
                        }
                    }
                }
            }
            //删除
            file.deleteOnExit();
        }catch (Exception e){
            System.out.println(e);
            System.out.println("上传图片报错");
            e.printStackTrace();
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        }
    }


    /**
     * MultipartFile 转换为 File 文件
     *
     * @param multipartFile
     * @return
     */
    public final static File transferToFile(MultipartFile multipartFile) {
        //选择用缓冲区来实现这个转换即使用java 创建的临时文件 使用 MultipartFile.transferto()方法 。
        File file = null;
        String prefix = null;
        try {
            String originalFilename = multipartFile.getOriginalFilename();
            //获取文件后缀
            prefix = originalFilename.substring(originalFilename.lastIndexOf("."));
            file = File.createTempFile(originalFilename, prefix);    //创建临时文件
            multipartFile.transferTo(file);
            //删除
            file.deleteOnExit();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return file;
    }





    public static Workbook getWorkbookOut(MultipartFile mFile) throws IOException {
        if (mFile == null) {
            return null;
        }
        // 解析表格数据
        InputStream in;
        String fileName;
        in = mFile.getInputStream();
        fileName = getString(mFile.getOriginalFilename()).toLowerCase();
        Workbook book;
        if (fileName.endsWith(XLSX)) {
            book = new XSSFWorkbook(in);
        } else if (fileName.endsWith(XLS)) {
            POIFSFileSystem poifsFileSystem = new POIFSFileSystem(in);
            book = new HSSFWorkbook(poifsFileSystem);
        } else {
            return null;
        }
        in.close();
        return book;
    }



    private static String getString(String s) {
        if (s == null) {
            return "";
        }
        if (s.isEmpty()) {
            return s;
        }
        return s.trim();
    }


    public static MultipartFile getMultipartFile(File file) {
        FileItem item = new DiskFileItemFactory().createItem("file"
                , MediaType.MULTIPART_FORM_DATA_VALUE
                , true
                , file.getName());
        try (InputStream input = new FileInputStream(file);
             OutputStream os = item.getOutputStream()) {
            // 流转移
            IOUtils.copy(input, os);
        } catch (Exception e) {
            throw new IllegalArgumentException("Invalid file: " + e, e);
        }
        return new CommonsMultipartFile(item);
    }


}
